#include "cObject.h"

void cObject::SetObject(GLuint id_object, char* url_object, char* url_vShader, char* url_fShader, vector<char*> url_texture, Matrix ModelObject)
{
	//Get object's ID
	objID = id_object;
	
	//Get model
	Model = new cModel();
	Model->LoadModel(url_object);

	//Get object's program
	Shader = new cShader();
	objProgram = Shader->Init(url_vShader, url_fShader);

	//Get object's matrix
	ma_Model = ModelObject;

	//Get textureID
	cTexture *Texture = new cTexture;
	
	if(objID == 0)
	{
		Texture->LoadSkyDomeTexture(url_texture[0], url_texture[1], url_texture[2], url_texture[3], url_texture[4], url_texture[5]);
		objTextureID.push_back(Texture->GetTextureId());
	}
	else
	{
		for (int i = 0 ; i < (int)url_texture.size() ; i++) 
		{
			Texture->LoadTexture(url_texture[i]);
			objTextureID.push_back(Texture->GetTextureId());
		}
	}
	//Clear memory
	SAFE_DEL(Texture);
}

void cObject::Draw()
{
	glUseProgram(objProgram);

	GLint x = 0;

	if(objID != 0)
		ma_MVP = ma_Model * cCamera::GetInstance()->GetViewProjectionMatrix();
	else
	{
		Matrix ma_Scale;
		ma_Scale.SetIdentity();
		ma_Scale.SetScale(100, 100, 100);
		ma_MVP = ma_Model * ma_Scale * cCamera::GetInstance()->GetViewProjectionMatrix();
	}
	if(Shader->positionAttribute != -1)
	{
		glEnableVertexAttribArray(Shader->positionAttribute);
		glVertexAttribPointer(Shader->positionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), Model->m_aVertices->position.ptr);
	}
	
	if(Shader->texCoordAttribute != -1)
	{
		glEnableVertexAttribArray(Shader->texCoordAttribute);
		glVertexAttribPointer(Shader->texCoordAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Model->m_aVertices->texcoord.ptr);
	}
	if(Shader->a_normalL != -1)
	{
		glEnableVertexAttribArray(Shader->a_normalL);
		glVertexAttribPointer(Shader->a_normalL, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Model->m_aVertices->normal.ptr);
	}
	if(Shader->a_tangentL != -1)
	{
		glEnableVertexAttribArray(Shader->a_tangentL);
		glVertexAttribPointer(Shader->a_tangentL, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Model->m_aVertices->tangent.ptr);
	}
	if(Shader->a_bitangentL != -1)
	{
		glEnableVertexAttribArray(Shader->a_bitangentL);
		glVertexAttribPointer(Shader->a_bitangentL, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Model->m_aVertices->tangent.ptr);
	}

	if(Shader->skyDomeUniform != -1)
	{
		glActiveTexture(GL_TEXTURE0 + x);
		glBindTexture(GL_TEXTURE_CUBE_MAP, objTextureID.at(0));
		glUniform1i(Shader->skyDomeUniform, x);
		x++;
	}

	if (Shader->textureUniform != -1)
	{
		glActiveTexture(GL_TEXTURE0 + x);
		glBindTexture(GL_TEXTURE_2D, objTextureID.at(0));
		glUniform1i(Shader->textureUniform, x);
		x++;
	}
	if (Shader->u_NormalMap != -1)
	{
		glActiveTexture(GL_TEXTURE0 + x);
		glBindTexture(GL_TEXTURE_2D, objTextureID.at(0));
		glUniform1i(Shader->u_NormalMap, x);
		x++;
	}
	if(Shader->Terrain_heightmap!= -1)
	{
		glActiveTexture(GL_TEXTURE0+x );
		glBindTexture(GL_TEXTURE_2D, objTextureID.at(x));
		glUniform1i(Shader->Terrain_heightmap,x);
		x++;
	}
	
	if(Shader->Terrain_grass!= -1)
	{
		glActiveTexture(GL_TEXTURE0+x );
		glBindTexture(GL_TEXTURE_2D, objTextureID.at(x));
		glUniform1i(Shader->Terrain_grass,x);
		x++;
	}
	if(Shader->Fire != -1)
	{
		glActiveTexture(GL_TEXTURE0+x );
		glBindTexture(GL_TEXTURE_2D, objTextureID.at(x));
		glUniform1i(Shader->Fire,x);
		x++;
	}
	if(Shader->teapot != -1)
	{
		glActiveTexture(GL_TEXTURE0+x );
		glBindTexture(GL_TEXTURE_2D, objTextureID.at(x));
		glUniform1i(Shader->teapot,x);
		x++;
	}
	
	if(Shader->Fire_mask != -1)
	{
		glActiveTexture(GL_TEXTURE0+x );
		glBindTexture(GL_TEXTURE_2D, objTextureID.at(x));
		glUniform1i(Shader->Fire_mask,x);
		x++;
	}
	if(Shader->Fire_map != -1)
	{
		glActiveTexture(GL_TEXTURE0+x );
		glBindTexture(GL_TEXTURE_2D, objTextureID.at(x));
		glUniform1i(Shader->Fire_map,x);
		x++;
	}
	if(Shader->Uniformincrease != -1)
	{
		static float increase=0.0;
		if (increase >1) increase = 0.0;
		increase += (float)0.01;
		glUniform1f(Shader->Uniformincrease, increase);

	}
	if(Shader->mvpMatrixUniform != -1)
	{
		glUniformMatrix4fv(Shader->mvpMatrixUniform, 1, GL_FALSE, (GLfloat*)ma_MVP.m);
	}
	if(Shader->u_W != -1)
	{
		glUniformMatrix4fv(Shader->u_W, 1, GL_FALSE, (GLfloat*)ma_Model.m);
	}
	if(Shader->matTransposeInverseUniform != -1)
	{
		Matrix a; 
		a.SetIdentity();
		a= ma_Model* cCamera::GetInstance()->GetViewMatrix();
		a.Transpose();
		glUniformMatrix4fv(Shader->matTransposeInverseUniform, 1, GL_FALSE, (GLfloat*)a.m);
	}
	if(Shader->matViewModel != -1)
	{
		Matrix a; 
		a.SetIdentity();
		a= ma_Model* cCamera::GetInstance()->GetViewMatrix();
		a.Transpose();
		glUniformMatrix4fv(Shader->matViewModel, 1, GL_FALSE, (GLfloat*)a.m);
	}
	if(Shader->Camera_Position != -1)
	{
		glEnableVertexAttribArray(Shader->Camera_Position);
		glVertexAttribPointer(Shader->Camera_Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Model->m_aVertices->position.ptr);
		
	}
	if(Shader->normalAttribute != -1)
	{
		glEnableVertexAttribArray(Shader->normalAttribute);
		glVertexAttribPointer(Shader->normalAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Model->m_aVertices->normal.ptr);
	}
	if(Shader->step != -1)
	{
	
		int k=50;
		float x = 1.0f/720;
		float y = 1.0f/960;
		float z = sqrt(2.0f) / 2.0f * x;
		float w = sqrt(2.0f) / 2.0f * y;
		glUniform4f(Shader->step,k*x, k*y, k*z, k*w);
	}
	//Enable Test methods;
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glDrawElements(GL_TRIANGLES, Model->m_iNumIndices, GL_UNSIGNED_INT, Model->m_aIndices);
}
